www.gusucode.com > VC++ 密码探测器 > VC++ 密码探测器/gusucode/PwdSpyHk/PwdSpyHk.cpp
// If you're compiling this using VC++5 you must define STRICT. // If you're using VC++6 it works without this define, so // obviously Microsoft changed the header files to define it // for you. For more info see the following article in the MSDN: // TN012: Using MFC with Windows 3.1 Robustness Features #ifndef STRICT #define STRICT 1 #endif #include <windows.h> #include <tchar.h> #include <crtdbg.h> #include "PwdSpyHk.h" #include "IPC.h" // Global variables static HHOOK g_hHook = NULL; // 钩子句柄 static DWORD g_dwThreadId = 0; // 被挂钩的线程 static HINSTANCE g_hinstDLL = NULL; // 该DLL的句柄 static CIPC g_obIPC; // 用来保护共享的资源,连接主进程和被钩进程的钩子函数 static UINT g_wmScanPassword = RegisterWindowMessage(IPC_CUSTOM_MSG); // Since this DLL is loaded by both PasswordSpy and the remote (or hooked) process, // each function in this DLL is listed which of the two processes calls that function. //*********************************************** BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { // 该DLL被两个进程调用 switch(fdwReason) { case DLL_PROCESS_ATTACH: // DLL映射进进程地址空间 g_hinstDLL = hinstDLL; // This call disables the DLL_THREAD_ATTACH and DLL_THREAD_DETACH // messages. DllMain should not get called with those messages. DisableThreadLibraryCalls(GetModuleHandle(PWDSPY_HOOK_DLL)); break; case DLL_THREAD_ATTACH: // 创建线程 break; case DLL_THREAD_DETACH: // 存在的线程. break; case DLL_PROCESS_DETACH: // DLL从进程中卸载 break; } return TRUE; } //*********************************************** bool WINAPI InstallHook(const DWORD dwThreadId) { // 该函数仅被PasswordSpy调用 _ASSERTE(dwThreadId); bool bSuccess = false; try { // 是否想挂钩的线程已经被钩住了 if(g_dwThreadId == dwThreadId) return true; // 如果已经挂钩在另一个线程上,先把钩子解除 if(g_dwThreadId != dwThreadId && g_hHook != NULL) RemoveHook(); //存储挂钩的线程句柄 if((g_dwThreadId = dwThreadId) != 0) { // 锁住共享的资源 g_obIPC.Lock(); g_obIPC.CreateIPCMMF(); //安装钩子 g_hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hinstDLL, g_dwThreadId); if(g_hHook != NULL) { // 进入共享资源,存储钩子句柄 DWORD dwData = (DWORD)g_hHook; g_obIPC.WriteIPCMMF((LPBYTE)&dwData, sizeof(dwData)); bSuccess = true; // 发一个消息到被钩线程队列,强迫调用钩子程序 PostThreadMessage(dwThreadId, WM_NULL, 0, 0); } } } catch(...) {} // 解开共享的资源 g_obIPC.Unlock(); return bSuccess; } //*********************************************** bool WINAPI RemoveHook(void) { // 该函数仅被PasswordSpy调用 bool bSuccess = false; try { if(g_hHook != NULL) { //卸载钩子 bSuccess = UnhookWindowsHookEx(g_hHook) ? true : false; g_hHook = NULL; g_dwThreadId = 0; } } catch(...) {} return bSuccess; } //*********************************************** bool WINAPI ScanPassword(const HWND hWnd, const HWND hPwdSpyWnd) //扫描密码 { // 该函数仅被PasswordSpy调用 bool bSuccess = false; try { if(g_dwThreadId != 0 && hWnd != NULL && hPwdSpyWnd != NULL) { //向被钩线程的子窗口发消息 PostThreadMessage(g_dwThreadId, g_wmScanPassword, (WPARAM)hWnd, (LPARAM)hPwdSpyWnd); bSuccess = true; } } catch(...) {} return bSuccess; } //*********************************************** LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) { // 该函数仅被被钩的进程调用 try { if(g_hHook == NULL) { // 从共享区读出钩子句柄 DWORD dwData = 0, dwSize = sizeof(dwData); g_obIPC.Lock(); g_obIPC.OpenIPCMMF(); g_obIPC.ReadIPCMMF((LPBYTE)&dwData, dwSize); g_obIPC.Unlock(); g_hHook = (HHOOK)dwData; } if(nCode >= 0) { HWND hWnd = NULL; // 拥有密码的窗口句柄,在被钩线程上 HWND hPwdSpyWnd = NULL; // PasswordSpy 窗口句柄, so we can SendMessage back MSG *pMsg = (MSG*)lParam; // 是否是我们自己发出的消息 if(pMsg->message == g_wmScanPassword) { hWnd = (HWND)pMsg->wParam; hPwdSpyWnd = (HWND)pMsg->lParam; ExtractPassword(hWnd, hPwdSpyWnd);//得到密码 } } } catch(...) {} // Always call the next hook in the chain return CallNextHookEx(g_hHook, nCode, wParam, lParam); } //*********************************************** void ExtractPassword(const HWND hWnd, const HWND hPwdSpyWnd) { // 该函数仅被被钩的进程调用 _ASSERTE(hWnd); _ASSERTE(hPwdSpyWnd); try { TCHAR szBuffer[256] = {_T('\0')}; //被钩进程得到自己某个窗口的内容 SendMessage(hWnd, WM_GETTEXT, sizeof(szBuffer) / sizeof(TCHAR), (LPARAM)szBuffer); // 利用WM_COPYDATA把密码发送回PasswordSpy COPYDATASTRUCT cds = {0}; cds.dwData = (DWORD)hWnd; cds.cbData = (lstrlen(szBuffer) + 1) * sizeof(TCHAR); cds.lpData = szBuffer; //将得到的密码返回给hPwdSpy窗口 SendMessage(hPwdSpyWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds); } catch(...) {} }